package com.yanqu.road.logic.activity.foxcard;

import com.yanqu.road.dao.impl.activity.foxcard.FoxCardConfigDaoImpl;
import com.yanqu.road.entity.activity.ActivityConfig;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.foxcard.FoxEffectCard;
import com.yanqu.road.entity.activity.foxcard.FoxHandCard;
import com.yanqu.road.entity.activity.foxcard.FoxSaleCard;
import com.yanqu.road.entity.activity.foxcard.FoxTreeCard;
import com.yanqu.road.entity.activity.foxcard.config.*;
import com.yanqu.road.logic.activity.foxcard.game.eFoxCardType;
import com.yanqu.road.pb.activity.FoxCardProto;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;

public class FoxCardConfig {
    private ActivityInfo activityInfo;
    private RandomHelper randomHelper = new RandomHelper();

    private Map<String, FoxCardProto.FoxCardConfigSyncMsg.Builder> configMsgMap = new HashMap<>();

    private Map<Integer, FoxCardLotteryConfig> lotteryConfigMap = new HashMap<>();
    private List<FoxCardLotterySettleConfig> lotterySettleConfigList = new ArrayList<>();
    private List<FoxCardMagicWeaponConfig> comboConfigs = new ArrayList<>();

    private List<FoxCardTreeLevelConfig> treeLevelConfigList = new ArrayList<>();
    private Map<Integer, FoxCardLabelConfig> labelConfigMap = new HashMap<>();
    private Map<Integer, FoxCardRoundConfig> roundConfigMap = new HashMap<>();
    private Map<Integer, FoxCardLimitConfig> limitConfigMap = new HashMap<>();
    private Map<Integer, FoxCardChapterConfig> chapterConfigMap = new HashMap<>();
    private Map<Integer, FoxCardEffectCardConfig> effectCardConfigMap = new HashMap<>();
    private Map<Integer, List<FoxCardEffectCardConfig>> effectCardConfigQualityMap = new HashMap<>();
    private Map<Integer, FoxCardMagicWeaponConfig> magicWeaponConfigMap = new HashMap<>();
    private Map<Integer, FoxCardSpellConfig> spellConfigMap = new HashMap<>();
    private Map<Integer, FoxCardSorceryConfig> sorceryConfigMap = new HashMap<>();
    private Map<Integer, FoxCardCouponConfig> couponConfigMap = new HashMap<>();
    private Map<Integer, FoxCardShopConfig> shopConfigMap = new HashMap<>();
    private Map<Integer, FoxCardBuffConfig> buffConfigMap = new HashMap<>();

    private List<Integer> treeLotteryAutoLimitPoints = new ArrayList<>(); //21点抽奖自动可选择停下的范围值 N1最小值 N2最大值
    private int scoreItemId = 101702; //积分道具id
    private int lotteryPowerId = 123800; //抽奖体力道具id
    private int FOX_ENDLESS_MODE_MISSION = 24; //过了该配置关卡，后续就是无尽模式
    private int treeInitPower = 30; //初始体力
    private int powerRecoverCD = 900; //体力恢复一点的CD秒
    private int unlockAutoLotteryNum = 3; //解锁自动抽奖次数
    private int guaranteeUnlockPerNum = 2; //每N轮拿一下未解锁的卡
    private int unlockGuaranteeNum = 5; //开始保底未解锁卡的轮次
    private int freeGameTimes = 10; //免费游戏次数
    private int startGameItemId = 123814; //开始游戏道具id
    private List<Integer> gameInitParams = new ArrayList<>();//初始参数(金币|出牌次数|弃牌次数|手牌数量上限|小丑牌上限|消耗牌上限）
    private List<Integer> shopRefreshParams = new ArrayList<>();//商店刷新金币（初始|递增值）
    private int shopSaleCardNum = 2; //商店出售卡牌数量
    private int shopSaleCardPackNum = 2; //商店出售卡包数量
    private int shopSaleCouponNum = 1; //商店出售优惠券数量
    private int handCardInitGold = 1; //手牌初始价值
    private int goldInterestNumNeed = 5; //每N个金币获得利息
    private int goldInterestAdd = 1; //获得利息数量
    private int goldInterestMax = 10; //最大利息上限
    private int salePriceOff = 500; //出售价格折扣,千分比
    private int shopEffectCardPoolNum = 50; //商店可刷的卡牌池数量
    private int effectCardVersionProbability = 200; //小丑牌版本概率
    private Property handCardEffectProbabilityProperty = new Property(); //手牌效果属性

    private Map<Integer, Integer> pointToScoreMap = new HashMap<>(); //牌面点数对应的分

    private Map<Integer, Integer> treeLotteryRandomPool = new HashMap<>(); //21点抽奖随机池
    private List<List<Integer>> guaranteeList = new ArrayList<>(); //保底配置

    private List<List<Integer>> guideLotteryList = new ArrayList<>();//新手引导前N抽

    private int initGuaranteeNum = 10; //初始保底轮次
    private int exRewardPoint = 21; //额外奖励点数

    private List<Integer> goldenRecallParams = new ArrayList<>();
    private Map<Integer, Integer> recallLotteryRandomPool = new HashMap<>(); //回忆助力抽奖池
    private Map<Integer, List<Integer>> recallBalanceParamsMap = new HashMap<>(); //回忆助力动态调整参数
    private List<Integer> recallCompareParams = new ArrayList<>();
    private int goldenGuaranteeNum = 3; //第N次回忆必定金色保底

    public FoxCardConfig(ActivityInfo activityInfo, Map<String, ActivityConfig> activityConfigMap) {
        this.activityInfo = activityInfo;
        int activityId = activityInfo.getActivityId();
        this.lotteryConfigMap = new FoxCardConfigDaoImpl().getFoxCardLotteryConfig(activityId);
        this.lotterySettleConfigList = new ArrayList<>(new FoxCardConfigDaoImpl().getFoxCardLotterySettleConfig(activityId).values());
        this.treeLevelConfigList = new ArrayList<>(new FoxCardConfigDaoImpl().getFoxCardTreeLevelConfig(activityId).values());
        this.treeLevelConfigList.sort((o1, o2) -> {
            return Integer.compare(o1.getLevel(), o2.getLevel());
        });
        this.labelConfigMap = new FoxCardConfigDaoImpl().getFoxCardLabelConfig(activityId);
        this.roundConfigMap = new FoxCardConfigDaoImpl().getFoxCardRoundConfig(activityId);
        this.limitConfigMap = new FoxCardConfigDaoImpl().getFoxCardLimitConfig(activityId);
        this.chapterConfigMap = new FoxCardConfigDaoImpl().getFoxCardChapterConfig(activityId);
        this.effectCardConfigMap = new FoxCardConfigDaoImpl().getFoxCardEffectCardConfig(activityId);
        this.magicWeaponConfigMap = new FoxCardConfigDaoImpl().getFoxCardMagicWeaponConfig(activityId);
        this.comboConfigs = new ArrayList<>(magicWeaponConfigMap.values());
        this.comboConfigs.sort(Comparator.comparingInt(FoxCardMagicWeaponConfig::getId));//按牌型排序 从小到大
        this.spellConfigMap = new FoxCardConfigDaoImpl().getFoxCardSpellConfig(activityId);
        this.sorceryConfigMap = new FoxCardConfigDaoImpl().getFoxCardSorceryConfig(activityId);
        this.couponConfigMap = new FoxCardConfigDaoImpl().getFoxCardCouponConfig(activityId);
        this.shopConfigMap = new FoxCardConfigDaoImpl().getFoxCardShopConfig(activityId);
        this.buffConfigMap = new FoxCardConfigDaoImpl().getFoxCardBuffConfig(activityId);

        for (FoxCardEffectCardConfig cardConfig : this.effectCardConfigMap.values()) {
            List<FoxCardEffectCardConfig> list = effectCardConfigQualityMap.get(cardConfig.getQuality());
            if (list == null) {
                list = new ArrayList<>();
                effectCardConfigQualityMap.put(cardConfig.getQuality(), list);
            }
            list.add(cardConfig);
        }

        this.treeLotteryAutoLimitPoints = StringUtils.stringToIntegerList(activityConfigMap.get("FOX_BALCKJACK_STOP_RANGE").getValue(), "\\|");
        this.scoreItemId = activityConfigMap.get("EXCHANGE_SCORE_ITEM_ID").getIntValue();
        this.lotteryPowerId = activityConfigMap.get("FOX_ENERGY_ITEM_ID").getIntValue();
        this.FOX_ENDLESS_MODE_MISSION = activityConfigMap.get("FOX_ENDLESS_MODE_MISSION").getIntValue();
        this.treeInitPower = activityConfigMap.get("FOX_INITIAL_ENERGY").getIntValue();
        this.powerRecoverCD = activityConfigMap.get("FOX_ENERGY_RECOVER").getIntValue();
        this.unlockAutoLotteryNum = activityConfigMap.get("FOX_BALCKJACK_AUTO_SELECT").getIntValue();
        List<Integer> list = StringUtils.stringToIntegerList(activityConfigMap.get("FOX_BALCKJACK_ROLL_GUARANTEES").getValue(), "\\|");
        this.unlockGuaranteeNum = list.get(0);
        this.guaranteeUnlockPerNum = list.get(1);
        this.freeGameTimes = activityConfigMap.get("FOX_CHAPTR_DAILY_FREE_JOIN_NUMBER").getIntValue();
        this.startGameItemId = activityConfigMap.get("FOX_CHAPTR_JOIN_ITEM_ID").getIntValue();
        this.gameInitParams = StringUtils.stringToIntegerList(activityConfigMap.get("FOX_INITIAL_PARAM").getValue(), "\\|");
        this.shopRefreshParams = StringUtils.stringToIntegerList(activityConfigMap.get("FOX_STORE_REFRESH_GOLD").getValue(), "\\|");
        list = StringUtils.stringToIntegerList(activityConfigMap.get("FOX_STORE_ITEM_INITIAL_NUMBER").getValue(), "\\|");
        this.shopSaleCardNum = list.get(0);
        this.shopSaleCardPackNum = list.get(1);
        this.shopSaleCouponNum = list.get(2);
        this.handCardInitGold = activityConfigMap.get("FOX_STORE_POKER_GOLD").getIntValue();
        list = StringUtils.stringToIntegerList(activityConfigMap.get("FOX_INTEREST_PARAM").getValue(), "\\|");
        this.goldInterestNumNeed = list.get(0);
        this.goldInterestAdd = list.get(1);
        this.goldInterestMax = list.get(2);
        this.salePriceOff = activityConfigMap.get("FOX_SELL_GOLD_PARAM").getIntValue();
        this.shopEffectCardPoolNum = activityConfigMap.get("FOX_STORE_CARD_REFRESH_MAX_NUM").getIntValue();

        for (String s : activityConfigMap.get("FOX_INITIALDECKS_POINT_AND_SCORE").getValue().split("\\|")) {
            List<Integer> params = StringUtils.stringToIntegerList(s, ";");
            pointToScoreMap.put(params.get(0), params.get(1));
        }

        for (FoxCardLotteryConfig lotteryConfig : lotteryConfigMap.values()) {
            treeLotteryRandomPool.put(lotteryConfig.getId(), lotteryConfig.getWeight());
        }

        for (String s : activityConfigMap.get("FOX_BALCKJACK_ROLL_GUARANTEES_POOL").getValue().split("\\|")) {
            List<Integer> points = StringUtils.stringToIntegerList(s, ";");
            guaranteeList.add(points);
        }
        this.effectCardVersionProbability = activityConfigMap.get("FOX_EFFECT_CARD_BUFF_PROBABILITY").getIntValue();
        this.handCardEffectProbabilityProperty = PropertyHelper.parseStringToProperty(activityConfigMap.get("FOX_POKER_BUFF_PROBABILITY").getValue());
        for (String s : activityConfigMap.get("FOX_GUIDE_ROLL").getValue().split("\\|")) {
            List<Integer> params = StringUtils.stringToIntegerList(s, ";");
            this.guideLotteryList.add(params);
        }
        this.initGuaranteeNum = activityConfigMap.get("FOX_21_INITIAL_GUARANTEES").getIntValue();
        this.goldenRecallParams = StringUtils.stringToIntegerList(activityConfigMap.get("FOX_GOLDEN_RECALL_POWER_PARAM").getValue(), "\\|");
        for (String s : activityConfigMap.get("FOX_RECALL_POWER_GUARANTEES").getValue().split("\\|")) {
            List<Integer> list1 = StringUtils.stringToIntegerList(s, ";");
            this.recallLotteryRandomPool.put(list1.get(0), list1.get(1));
        }
        this.recallBalanceParamsMap.put(2, StringUtils.stringToIntegerList(activityConfigMap.get("FOX_RECALL_POWER_BALANCE_PARAM_2").getValue(), "\\|"));
        this.recallBalanceParamsMap.put(3, StringUtils.stringToIntegerList(activityConfigMap.get("FOX_RECALL_POWER_BALANCE_PARAM_3").getValue(), "\\|"));
        this.recallBalanceParamsMap.put(4, StringUtils.stringToIntegerList(activityConfigMap.get("FOX_RECALL_POWER_BALANCE_PARAM_4").getValue(), "\\|"));
        this.recallBalanceParamsMap.put(5, StringUtils.stringToIntegerList(activityConfigMap.get("FOX_RECALL_POWER_BALANCE_PARAM_5").getValue(), "\\|"));
        this.recallCompareParams = StringUtils.stringToIntegerList(activityConfigMap.get("FOX_RECALL_POWER_TRIGGER_BALANCE").getValue(), "\\|");
        this.goldenGuaranteeNum = activityConfigMap.get("FOX_GOLDEN_RECALL_GUARANTEES").getIntValue();
    }

    public int getActivityId() {
        return activityInfo.getActivityId();
    }

    public RandomHelper getRandomHelper() {
        return randomHelper;
    }

    public ActivityInfo getActivityInfo() {
        return activityInfo;
    }

    public Map<Integer, FoxCardLotteryConfig> getLotteryConfigMap() {
        return lotteryConfigMap;
    }

    public List<FoxCardLotterySettleConfig> getLotterySettleConfigList() {
        return lotterySettleConfigList;
    }

    public List<FoxCardMagicWeaponConfig> getComboConfigs() {
        return comboConfigs;
    }

    public List<FoxCardTreeLevelConfig> getTreeLevelConfigList() {
        return treeLevelConfigList;
    }

    public Map<Integer, FoxCardLabelConfig> getLabelConfigMap() {
        return labelConfigMap;
    }

    public Map<Integer, FoxCardRoundConfig> getRoundConfigMap() {
        return roundConfigMap;
    }

    public Map<Integer, FoxCardLimitConfig> getLimitConfigMap() {
        return limitConfigMap;
    }

    public Map<Integer, FoxCardChapterConfig> getChapterConfigMap() {
        return chapterConfigMap;
    }

    public Map<Integer, FoxCardEffectCardConfig> getEffectCardConfigMap() {
        return effectCardConfigMap;
    }

    public Map<Integer, FoxCardMagicWeaponConfig> getMagicWeaponConfigMap() {
        return magicWeaponConfigMap;
    }

    public Map<Integer, FoxCardSpellConfig> getSpellConfigMap() {
        return spellConfigMap;
    }

    public Map<Integer, FoxCardSorceryConfig> getSorceryConfigMap() {
        return sorceryConfigMap;
    }

    public Map<Integer, FoxCardCouponConfig> getCouponConfigMap() {
        return couponConfigMap;
    }

    public Map<Integer, FoxCardShopConfig> getShopConfigMap() {
        return shopConfigMap;
    }

    public Map<Integer, FoxCardBuffConfig> getBuffConfigMap() {
        return buffConfigMap;
    }

    public List<Integer> getTreeLotteryAutoLimitPoints() {
        return treeLotteryAutoLimitPoints;
    }

    public int getScoreItemId() {
        return scoreItemId;
    }

    public int getLotteryPowerId() {
        return lotteryPowerId;
    }

    public int getFOX_ENDLESS_MODE_MISSION() {
        return FOX_ENDLESS_MODE_MISSION;
    }

    public int getTreeInitPower() {
        return treeInitPower;
    }

    public int getPowerRecoverCD() {
        return powerRecoverCD;
    }

    public int getUnlockAutoLotteryNum() {
        return unlockAutoLotteryNum;
    }

    public int getGuaranteeUnlockPerNum() {
        return guaranteeUnlockPerNum;
    }

    public int getUnlockGuaranteeNum() {
        return unlockGuaranteeNum;
    }

    public int getFreeGameTimes() {
        return freeGameTimes;
    }

    public int getStartGameItemId() {
        return startGameItemId;
    }

    public List<Integer> getGameInitParams() {
        return gameInitParams;
    }

    public List<Integer> getShopRefreshParams() {
        return shopRefreshParams;
    }

    public int getShopSaleCardNum() {
        return shopSaleCardNum;
    }

    public int getShopSaleCardPackNum() {
        return shopSaleCardPackNum;
    }

    public int getShopSaleCouponNum() {
        return shopSaleCouponNum;
    }

    public int getHandCardInitGold() {
        return handCardInitGold;
    }

    public int getGoldInterestNumNeed() {
        return goldInterestNumNeed;
    }

    public int getGoldInterestAdd() {
        return goldInterestAdd;
    }

    public int getGoldInterestMax() {
        return goldInterestMax;
    }

    public int getSalePriceOff() {
        return salePriceOff;
    }

    public int getShopEffectCardPoolNum() {
        return shopEffectCardPoolNum;
    }

    public Map<String, FoxCardProto.FoxCardConfigSyncMsg.Builder> getConfigMsgMap() {
        return configMsgMap;
    }

    public void setConfigMsgMap(Map<String, FoxCardProto.FoxCardConfigSyncMsg.Builder> configMsgMap) {
        this.configMsgMap = configMsgMap;
    }

    public FoxCardProto.FoxCardConfigSyncMsg.Builder getConfigMsg(String language) {
        return configMsgMap.get(language);
    }

    public void setConfigMsg(String language, FoxCardProto.FoxCardConfigSyncMsg.Builder configMsg) {
        configMsgMap.put(language, configMsg);
    }

    public Map<Integer, Integer> getPointToScoreMap() {
        return pointToScoreMap;
    }

    public int getPointScore(int point) {
        return pointToScoreMap.getOrDefault(point, 0);
    }

    public boolean checkAutoLotteryEndPoint(int endAmountPoints) {
        return endAmountPoints >= treeLotteryAutoLimitPoints.get(0) && endAmountPoints <= treeLotteryAutoLimitPoints.get(1);
    }

    public int calcTreeCardsPoint(List<FoxTreeCard> treeCards) {
        int point = 0;
        for (FoxTreeCard treeCard : treeCards) {
            point += treeCard.getPoint();
        }
        return point;
    }

    public boolean checkPointCanContinueLottery(List<FoxTreeCard> treeCards) {
        int point = calcTreeCardsPoint(treeCards);
        int cardNum = treeCards.size();
        for (FoxCardLotterySettleConfig settleConfig : lotterySettleConfigList) {
            Integer minNum = settleConfig.getParams().get(0);
            Integer maxNum = settleConfig.getParams().get(1);
            if (settleConfig.getType() == 1) {//点数范围
                if (point >= minNum && point <= maxNum) {
                    return settleConfig.getRollType() != 2;
                }
            } else {//N1张小于N2点
                if (cardNum >= minNum && point <= maxNum) {
                    return false;//不能继续了
                } else {
                    return true;
                }
            }

        }
        return false;
    }

    public boolean checkPointCanEndLottery(List<FoxTreeCard> treeCards) {
        int point = calcTreeCardsPoint(treeCards);
        int cardNum = treeCards.size();
        //优先判断类型2
        for (FoxCardLotterySettleConfig settleConfig : lotterySettleConfigList) {
            Integer minNum = settleConfig.getParams().get(0);
            Integer maxNum = settleConfig.getParams().get(1);
            if (settleConfig.getType() == 2) {//N1张小于N2点
                if (cardNum >= minNum && point <= maxNum) {
                    return true;//不能继续了
                }
            }
        }
        for (FoxCardLotterySettleConfig settleConfig : lotterySettleConfigList) {
            Integer minNum = settleConfig.getParams().get(0);
            Integer maxNum = settleConfig.getParams().get(1);
            if (settleConfig.getType() == 1) {//点数范围
                if (point >= minNum && point <= maxNum) {
                    return settleConfig.getRollType() != 0;
                }
            }
        }
        return false;
    }

    public FoxCardLotteryConfig getLotteryConfig(int lotteryId) {
        return lotteryConfigMap.get(lotteryId);
    }

    public List<FoxCardEffectCardConfig> getEffectCardConfigListByQuality(int quality) {
        List<FoxCardEffectCardConfig> list = new ArrayList<>(effectCardConfigQualityMap.get(quality));
        return list;
    }

    /**
     * 随机保底配置
     *
     * @return
     */
    public List<Integer> randomOnceTreeGuaranteeList() {
        List<Integer> list = (List<Integer>) randomHelper.randomList(guaranteeList);
        return new ArrayList<>(list);
    }

    public FoxCardLotteryConfig calcLotteryConfigQualityByPoint(int point) {
        for (FoxCardLotteryConfig lotteryConfig : lotteryConfigMap.values()) {
            if (point >= lotteryConfig.getPointParams().get(0) && point <= lotteryConfig.getPointParams().get(1)) {
                return lotteryConfig;
            }
        }
        return null;
    }

    public FoxCardLotterySettleConfig calcLotterySettleConfigBuyTotalPoint(List<FoxTreeCard> treeCards) {
        int totalPoint = calcTreeCardsPoint(treeCards);
        int cardNum = treeCards.size();
        //优先判断类型2
        for (FoxCardLotterySettleConfig settleConfig : lotterySettleConfigList) {
            Integer minNum = settleConfig.getParams().get(0);
            Integer maxNum = settleConfig.getParams().get(1);
            if (settleConfig.getType() == 2) {//N1张小于N2点
                if (cardNum >= minNum && totalPoint <= maxNum) {
                    return settleConfig;//不能继续了
                }
            }
        }
        for (FoxCardLotterySettleConfig settleConfig : lotterySettleConfigList) {
            Integer minNum = settleConfig.getParams().get(0);
            Integer maxNum = settleConfig.getParams().get(1);
            if (settleConfig.getType() == 1) {//点数范围
                if (totalPoint >= minNum && totalPoint <= maxNum) {
                    return settleConfig;
                }
            }
        }
        return null;
    }

    /**
     * @param treeCards       解签中的卡
     * @param guaranteeAmount 保底前累计
     * @param lotteryAmount   累计抽取次数
     * @param lotteryRound    累计抽取轮次
     * @param unlockCards     已拥有的卡
     * @param guaranteePoints
     * @return
     */
    public FoxTreeCard randomOnceLotteryCard(List<FoxTreeCard> treeCards, int guaranteeAmount, int lotteryAmount, int lotteryRound, Set<Integer> unlockCards, List<Integer> guaranteePoints) {
        List<Integer> guideLottery = getGuideLottery(lotteryAmount);
        if (!guideLottery.isEmpty()) {
            int cardId = guideLottery.get(0);
            int point = guideLottery.get(1);
            FoxCardLotteryConfig lotteryConfig = calcLotteryConfigQualityByPoint(point);
            FoxTreeCard treeCard = new FoxTreeCard();
            treeCard.setLotteryId(lotteryConfig.getId());
            treeCard.setCardId(cardId);
            treeCard.setPoint(point);
            return treeCard;
        } else{
            boolean isNeedUnlockCard = false;
            if (lotteryRound >= getUnlockGuaranteeNum() && getUnlockGuaranteeNum() > 0 && getGuaranteeUnlockPerNum() > 0 &&
                    unlockCards.size() < getEffectCardConfigMap().size() && treeCards.isEmpty() && lotteryRound % getGuaranteeUnlockPerNum() == 0) {
                isNeedUnlockCard = true;
            }
            if (guaranteeAmount == 0) {//本轮保底,抽点数
                int idx = treeCards.size();
                Integer point = guaranteePoints.get(idx);
                FoxCardLotteryConfig lotteryConfig = calcLotteryConfigQualityByPoint(point);
                List<FoxCardEffectCardConfig> effectCardConfigs = getEffectCardConfigListByQuality(lotteryConfig.getQuality());
                List<FoxCardEffectCardConfig> filterCards = new ArrayList<>();
                if (isNeedUnlockCard) {
                    for (FoxCardEffectCardConfig effectCardConfig : effectCardConfigs) {
                        if (!unlockCards.contains(effectCardConfig.getId())) {
                            filterCards.add(effectCardConfig);
                        }
                    }
                    if (filterCards.isEmpty()) { //保底点数的卡都获得过了
                        filterCards = effectCardConfigs;
                    }
                } else  {
                    filterCards = effectCardConfigs;
                }
                FoxCardEffectCardConfig effectCardConfig = (FoxCardEffectCardConfig) randomHelper.randomList(filterCards);

                FoxTreeCard treeCard = new FoxTreeCard();
                treeCard.setLotteryId(lotteryConfig.getId());
                treeCard.setCardId(effectCardConfig.getId());
                treeCard.setPoint(point);
                return treeCard;

            } else if (isNeedUnlockCard) {
                //指定轮次后,每N轮的每轮第一张保底抽未解锁的卡,先抽卡再抽点数
                List<Integer> notUnlockCards = new ArrayList<>();
                for (FoxCardEffectCardConfig effectCardConfig : getEffectCardConfigMap().values()) {
                    if (!unlockCards.contains(effectCardConfig.getId())) {
                        notUnlockCards.add(effectCardConfig.getId());
                    }
                }
                Integer cardId = RandomHelper.getRandomList(notUnlockCards, 1).get(0);
                FoxCardEffectCardConfig effectCardConfig = getEffectCardConfigMap().get(cardId);
                //抽到卡后根据卡的品质抽点数
                Map<Integer, Integer> lotteryWightMap =new HashMap<>();
                for (FoxCardLotteryConfig lotteryConfig : lotteryConfigMap.values()) {
                    if (lotteryConfig.getQuality() == effectCardConfig.getQuality()) {
                        lotteryWightMap.put(lotteryConfig.getId(), lotteryConfig.getWeight());
                    }
                }
                int lotteryId = randomHelper.getRandomKeyByWeightEx(lotteryWightMap);
                FoxCardLotteryConfig lotteryConfig = getLotteryConfig(lotteryId);
                int minNum = lotteryConfig.getPointParams().get(0);
                int maxNum = lotteryConfig.getPointParams().get(1);
                int randomPoint = randomHelper.getRandomDistinctInteger(minNum, maxNum, 1).get(0);
                FoxTreeCard treeCard = new FoxTreeCard();
                treeCard.setLotteryId(lotteryConfig.getId());
                treeCard.setCardId(effectCardConfig.getId());
                treeCard.setPoint(randomPoint);
                return treeCard;
            } else {
                int lotteryId = randomHelper.getRandomKeyByWeightEx(treeLotteryRandomPool);
                FoxCardLotteryConfig lotteryConfig = getLotteryConfig(lotteryId);
                int quality = lotteryConfig.getQuality();
                int minNum = lotteryConfig.getPointParams().get(0);
                int maxNum = lotteryConfig.getPointParams().get(1);
                int randomPoint = randomHelper.getRandomDistinctInteger(minNum, maxNum, 1).get(0);
                List<FoxCardEffectCardConfig> effectCardConfigs = getEffectCardConfigListByQuality(quality);

                FoxCardEffectCardConfig effectCardConfig = (FoxCardEffectCardConfig) randomHelper.randomList(effectCardConfigs);

                FoxTreeCard treeCard = new FoxTreeCard();
                treeCard.setLotteryId(lotteryConfig.getId());
                treeCard.setCardId(effectCardConfig.getId());
                treeCard.setPoint(randomPoint);
                return treeCard;
            }
        }
    }

    public FoxTreeCard autoLotteryTreeCard(List<FoxTreeCard> treeCards, int guaranteeAmount, int endPoint, int lotteryAmount, int lotteryRound, Set<Integer> unlockCards, List<Integer> guaranteePoints) {
        if (!checkPointCanContinueLottery(treeCards)) {
            return null;
        }
        int point = calcTreeCardsPoint(treeCards);
        if (point >= endPoint) {
            return null;
        }
        return randomOnceLotteryCard(treeCards, guaranteeAmount, lotteryAmount, lotteryRound, unlockCards, guaranteePoints);
    }

    public FoxCardTreeLevelConfig getTreeLevelConfig(int level) {
        for (FoxCardTreeLevelConfig treeLevelConfig : treeLevelConfigList) {
            if (treeLevelConfig.getLevel() == level) {
                return treeLevelConfig;
            }
        }
        return null;
    }

    public int calcTreeLevel(int treeExp) {
        int level = 0;
        for (FoxCardTreeLevelConfig treeLevelConfig : treeLevelConfigList) {
            if (treeExp >= treeLevelConfig.getExp()) {
                level = treeLevelConfig.getLevel();
            } else {
                break;
            }
        }
        return level;
    }

    /**
     * 获得初始解锁的卡牌
     *
     * @return
     */
    public List<Integer> getInitEffectCardIds() {
        List<Integer> list = new ArrayList<>();
        for (FoxCardEffectCardConfig effectCardConfig : effectCardConfigMap.values()) {
            if (effectCardConfig.getIsInitial() == 1) {
                list.add(effectCardConfig.getId());
            }
        }
        return list;
    }

    /**
     * 随机一个标签
     *
     * @return
     */
    public int randomOnceLabel() {
        Map<Integer, Integer> labelMap = new HashMap<>();
        for (FoxCardLabelConfig labelConfig : labelConfigMap.values()) {
            labelMap.put(labelConfig.getId(), labelConfig.getWeight());
        }
        return randomHelper.getRandomKeyByWeightEx(labelMap);
    }

    /**
     * 随机一个boss限制
     *
     * @return
     */
    public int randomOnceBossLimit(int round, int stageId) {
        Map<Integer, Integer> limitMap = new HashMap<>();
        for (FoxCardLimitConfig limitConfig : limitConfigMap.values()) {
            if (!limitConfig.getChapterLimitList().contains(stageId)) {
                continue;
            }
            if (round >= limitConfig.getRoundLimitList().get(0) && round <= limitConfig.getRoundLimitList().get(1)) {
                limitMap.put(limitConfig.getId(), limitConfig.getWeight());
            }
        }
        return randomHelper.getRandomKeyByWeightEx(limitMap);
    }

    /**
     * 获得商店刷新价格
     *
     * @param times
     * @return
     */
    public int getShopRefreshPrice(int times) {
        int initPrice = shopRefreshParams.get(0);
        int addPrice = shopRefreshParams.get(1);
        return initPrice + addPrice * times;
    }

    /**
     * 随机商店的小丑牌品质
     *
     * @return
     */
    public int randomShopEffectCardQuality(Set<Integer> poolQualityHave) {
        Map<Integer, Integer> qualityWeightMap = new HashMap<>();
        for (FoxCardShopConfig shopConfig : shopConfigMap.values()) {
            Integer quality = shopConfig.getParamList().get(0);
            if (shopConfig.getPosition() == 1 && shopConfig.getCardType() == 1) {
                if (poolQualityHave != null && !poolQualityHave.isEmpty() && !poolQualityHave.contains(quality)) {
                    continue;
                }
                qualityWeightMap.put(quality, shopConfig.getWeight());
            }
        }
        return randomHelper.getRandomKeyByWeightEx(qualityWeightMap);
    }

    public int calcEffectCardPrice(FoxCardEffectCardConfig effectCardConfig, int versionEffect) {
        if (effectCardConfig == null) {
            return 0;
        }
        int price = effectCardConfig.getPrice();
        FoxCardBuffConfig buffConfig = getBuffConfigMap().get(versionEffect);
        if (buffConfig != null) {
            price += buffConfig.getGold();
        }
        return price;
    }

    public int calcConsumeCardPrice(int type, int configId, int versionEffect) {
        int price = 0;
        if (type == eFoxCardType.MAGIC_WEAPON.getValue()) {
            price = getMagicWeaponConfigMap().get(configId).getGold();
        } else if (type == eFoxCardType.SPELL.getValue()) {
            price = getSpellConfigMap().get(configId).getGold();
        } else if (type == eFoxCardType.SORCERY.getValue()) {
            price = getSorceryConfigMap().get(configId).getGold();
        }

        FoxCardBuffConfig buffConfig = getBuffConfigMap().get(versionEffect);
        if (buffConfig != null) {
            price += buffConfig.getGold();
        }
        return price;
    }

    public int calcHandCardPrice(int reinforceEffect, int versionEffect, int sealEffect) {
        int basePrice = getHandCardInitGold();
        FoxCardBuffConfig reinforceBuffConfig = getBuffConfigMap().get(reinforceEffect);
        FoxCardBuffConfig versionBuffConfig = getBuffConfigMap().get(versionEffect);
        FoxCardBuffConfig sealBuffConfig = getBuffConfigMap().get(sealEffect);
        if (reinforceBuffConfig != null) {
            basePrice += reinforceBuffConfig.getGold();
        }
        if (versionBuffConfig != null) {
            basePrice += versionBuffConfig.getGold();
        }
        if (sealBuffConfig != null) {
            basePrice += sealBuffConfig.getGold();
        }
        return basePrice;
    }

    public int randomReinforceEffect(int cardType) {
        int sortType = 1;
        if (cardType == eFoxCardType.HAND.getValue()) {//手牌
            int randomValue = randomHelper.next(1000);
            if (randomValue >= handCardEffectProbabilityProperty.getCountByGoodsId(sortType).intValue()) {
                return 0;
            }
        } else {//其他牌随机不到
            return 0;
        }
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardBuffConfig buffConfig : buffConfigMap.values()) {
            if (buffConfig.getSort() != sortType) {
                continue;
            }
            weightMap.put(buffConfig.getId(), buffConfig.getWeight());
        }
        int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
        return configId;
    }

    public int randomBuffId(int sortType) {
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardBuffConfig buffConfig : buffConfigMap.values()) {
            if (buffConfig.getSort() != sortType) {
                continue;
            }
            weightMap.put(buffConfig.getId(), buffConfig.getWeight());
        }
        int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
        return configId;
    }

    public int randomVersionEffect(int cardType, int couponAddValue) {
        if (cardType == eFoxCardType.EFFECT.getValue()) {//小丑牌
            int randomValue = randomHelper.next(1000);
            int checkValue = effectCardVersionProbability;
            if (couponAddValue > 0) {
                checkValue = BigDecimal.valueOf(checkValue).multiply(BigDecimal.valueOf(couponAddValue + 1000).divide(BigDecimal.valueOf(1000))).intValue();
            }
            if (randomValue >= checkValue) {
                return 0;
            }
        } else if (cardType == eFoxCardType.HAND.getValue()) {//手牌
            int randomValue = randomHelper.next(1000);
            int checkValue = handCardEffectProbabilityProperty.getCountByGoodsId(2).intValue();
            if (couponAddValue > 0) {
                checkValue = BigDecimal.valueOf(checkValue).multiply(BigDecimal.valueOf(couponAddValue + 1000).divide(BigDecimal.valueOf(1000))).intValue();
            }
            if (randomValue >= checkValue) {
                return 0;
            }
        } else {
            return 0;
        }
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardBuffConfig buffConfig : buffConfigMap.values()) {
            if (buffConfig.getSort() != 2) {
                continue;
            }
            if (cardType == eFoxCardType.HAND.getValue() && buffConfig.getSkillType() == 8) {//手牌不能有负片效果
                continue;
            }
            weightMap.put(buffConfig.getId(), buffConfig.getWeight());
        }
        int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
        return configId;
    }


    public int randomSealEffect(int cardType) {
        int sortType = 3;
        if (cardType == eFoxCardType.HAND.getValue()) {//手牌
            int randomValue = randomHelper.next(1000);
            if (randomValue >= handCardEffectProbabilityProperty.getCountByGoodsId(sortType).intValue()) {
                return 0;
            }
        } else {//其他牌随机不到
            return 0;
        }
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardBuffConfig buffConfig : buffConfigMap.values()) {
            if (buffConfig.getSort() != sortType) {
                continue;
            }
            weightMap.put(buffConfig.getId(), buffConfig.getWeight());
        }
        int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
        return configId;
    }

    public int randomHandCardSealEffect() {
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardBuffConfig buffConfig : buffConfigMap.values()) {
            if (buffConfig.getSort() != 3) {
                continue;
            }
            weightMap.put(buffConfig.getId(), buffConfig.getWeight());
        }
        int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
        return configId;
    }


    public FoxCardMagicWeaponConfig randomMagicWeapon() {
        return randomMagicWeapons(1, new HashSet<>()).get(0);
    }

    public List<FoxCardMagicWeaponConfig> randomMagicWeapons(int num, Set<Integer> excludeIds) {
        List<FoxCardMagicWeaponConfig> list = new ArrayList<>();
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardMagicWeaponConfig weaponConfig : magicWeaponConfigMap.values()) {
            if (excludeIds.contains(weaponConfig.getId())) {
                continue;
            }
            weightMap.put(weaponConfig.getId(), weaponConfig.getWeight());
        }
        for (int i = 0; i < num; i++) {
            int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
            FoxCardMagicWeaponConfig weaponConfig = magicWeaponConfigMap.get(configId);
            list.add(weaponConfig);
            weightMap.remove(configId);
        }
        return list;
    }

    public FoxCardSpellConfig randomSpell() {
        return randomSpells(1).get(0);
    }

    public List<FoxCardSpellConfig> randomSpells(int num) {
        List<FoxCardSpellConfig> list = new ArrayList<>();
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardSpellConfig spellConfig : spellConfigMap.values()) {
            weightMap.put(spellConfig.getId(), spellConfig.getWeight());
        }
        for (int i = 0; i < num; i++) {
            int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
            FoxCardSpellConfig spellConfig = spellConfigMap.get(configId);
            list.add(spellConfig);
            weightMap.remove(configId);
        }
        return list;
    }

    public FoxCardSorceryConfig randomSorcery() {
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardSorceryConfig sorceryConfig : sorceryConfigMap.values()) {
            weightMap.put(sorceryConfig.getId(), sorceryConfig.getWeight());
        }
        int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
        return sorceryConfigMap.get(configId);
    }

    public FoxCardCouponConfig randomCoupon(Set<Integer> coupons) {
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardCouponConfig couponConfig : couponConfigMap.values()) {
            if (coupons.contains(couponConfig.getId())) {
                continue;
            }
            if (couponConfig.getUnlockPremise() > 0) {//需要前置解锁
                if (!coupons.contains(couponConfig.getUnlockPremise())) {
                    continue;
                }
            }
            weightMap.put(couponConfig.getId(), couponConfig.getWeight());
        }
        if (weightMap.isEmpty()) {
            return null;
        }
        int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
        FoxCardCouponConfig couponConfig = couponConfigMap.get(configId);
        return couponConfig;
    }

    public List<FoxCardShopConfig> randomShopSalePack() {
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardShopConfig shopConfig : shopConfigMap.values()) {
            if (shopConfig.getPosition() != 2) {
                continue;
            }
            weightMap.put(shopConfig.getId(), shopConfig.getWeight());
        }
        List<FoxCardShopConfig> list = new ArrayList<>();
        for (int i = 0; i < shopSaleCardPackNum; i++) {
            int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
            FoxCardShopConfig shopConfig = shopConfigMap.get(configId);
            list.add(shopConfig);
        }
        return list;
    }

    /**
     * 计算利息
     *
     * @param gold
     * @param maxInterestGold
     * @return
     */
    public int calcInterest(int gold, int maxInterestGold) {
        int interest = gold / goldInterestNumNeed;
        int goldAdd = interest * goldInterestAdd;
        if (goldAdd > maxInterestGold) {
            goldAdd = maxInterestGold;
        }
        return goldAdd;
    }

    public List<FoxCardSorceryConfig> randomSorceryList(int cardNum) {
        List<FoxCardSorceryConfig> list = new ArrayList<>();
        Map<Integer, Integer> weightMap = new HashMap<>();
        for (FoxCardSorceryConfig sorceryConfig : sorceryConfigMap.values()) {
            weightMap.put(sorceryConfig.getId(), sorceryConfig.getWeight());
        }
        for (int i = 0; i < cardNum; i++) {
            int configId = randomHelper.getRandomKeyByWeightEx(weightMap);
            FoxCardSorceryConfig sorceryConfig = sorceryConfigMap.get(configId);
            list.add(sorceryConfig);
            weightMap.remove(configId);
        }
        return list;

    }

    /**
     * 点数是不是人头牌
     */
    public boolean isHeadCard(int point) {
        return point > 10;
    }

    /**
     * 点数是不是数字牌
     */
    public boolean isNumberCard(int point) {
        return point <= 10;
    }

    /**
     * 手牌是否石头牌,没点数也没花色
     *
     * @return
     */
    public boolean isNotPointAndNotColorHandCard(int reinforceEffect) {
        FoxCardBuffConfig buffConfig = getBuffConfigMap().get(reinforceEffect);
        if (buffConfig == null) {
            return false;
        }
        return buffConfig.getSkillType() == 6;
    }

    /**
     * 手牌是否万能花色
     */
    public boolean isAllColorHandCard(int reinforceEffect) {
        FoxCardBuffConfig buffConfig = getBuffConfigMap().get(reinforceEffect);
        if (buffConfig == null) {
            return false;
        }
        return buffConfig.getSkillType() == 3;
    }

    public List<FoxSaleCard> randomEffectCard(List<FoxEffectCard> haveEffectCards, int quality, int cardNum, int versionEffect, int couponAddValue) {
        Map<Integer, Integer> qualityNumMap = new HashMap<>();
        for (int i = 0; i < cardNum; i++) {
            int takeQuality = quality;
            if (quality <= 0) { //小丑牌随机品质
                takeQuality = randomShopEffectCardQuality(null);
            }
            qualityNumMap.put(takeQuality, qualityNumMap.getOrDefault(takeQuality, 0) + 1);
        }
        List<FoxSaleCard> saleCards = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : qualityNumMap.entrySet()) {
            Integer takeQuality = entry.getKey();
            Integer num = entry.getValue();

            List<FoxCardEffectCardConfig> configList = getEffectCardConfigListByQuality(takeQuality);
            List<FoxCardEffectCardConfig> list = new ArrayList<>();
            for (FoxCardEffectCardConfig effectCardConfig : configList) {
                if (haveEffectCards.stream().anyMatch(e -> e.getConfigId() == effectCardConfig.getId())) {
                    continue;
                }
                list.add(effectCardConfig);
            }


            List<FoxCardEffectCardConfig> randomList = RandomHelper.getRandomList(list, num);
            for (FoxCardEffectCardConfig effectCardConfig : randomList) {
                int takeVersionEffect = 0;
                if (versionEffect == -1) {
                    takeVersionEffect = randomVersionEffect(eFoxCardType.EFFECT.getValue(), couponAddValue);
                }
                FoxSaleCard saleCard = new FoxSaleCard();
                saleCard.setConfigId(effectCardConfig.getId());
                saleCard.setVersionEffect(takeVersionEffect);
                saleCard.setType(eFoxCardType.EFFECT.getValue());
                saleCard.setPrice(calcEffectCardPrice(effectCardConfig, versionEffect));
                saleCards.add(saleCard);
            }
        }

        return saleCards;
    }
    /**
     * 是否负片,不占用槽位
     */
    public boolean isBuffType8(int buffId) {
        FoxCardBuffConfig buffConfig = getBuffConfigMap().get(buffId);
        if (buffConfig == null) {
            return false;
        }
        return buffConfig.getSkillType() == 8;
    }

    /**
     * 获得牌型的基础分和基础倍率
     */
    public List<Long> calcComboBaseValues(int comboId, int level, int bossLimit) {
        long baseScore = 0;
        long baseMulti = 0;
        FoxCardMagicWeaponConfig weaponConfig = getMagicWeaponConfigMap().get(comboId);
        if (weaponConfig != null) {
            baseScore = (long)weaponConfig.getInitParamList().get(0) + (level - 1) * (long)weaponConfig.getParamList().get(0);
            baseMulti = (long)weaponConfig.getInitParamList().get(1) + (level - 1) * (long)weaponConfig.getParamList().get(1);
        }

        List<Long> values = new ArrayList<>();
        values.add(baseScore);
        values.add(baseMulti);
        return values;
    }

    /**
     * 获取顺子牌
     *
     * @param showCards
     * @param straightInterval 间隔最大值
     * @param straightMinNum 顺子的最小数量要求
     * @return
     */
    public List<FoxHandCard> getStraightCards(List<FoxHandCard> showCards, int straightInterval, int straightMinNum) {
        //相同点数去重
        List<FoxHandCard> filterCards = new ArrayList<>();
        for (FoxHandCard showCard : showCards) {
            boolean isRepeatPoint = false;
            for (FoxHandCard filterCard : filterCards) {
                if (filterCard.getPoint() == showCard.getPoint()) {
                    isRepeatPoint = true;
                    break;
                }
            }
            if (!isRepeatPoint) {
                filterCards.add(showCard);
            }
        }
        if (filterCards.size() < straightMinNum) {
            return new ArrayList<>();
        }
        List<List<FoxHandCard>> sequences = findAllStraightCards(filterCards, straightInterval, straightMinNum);

        if (sequences.isEmpty()) {
            return new ArrayList<>();
        }

//        Set<FoxHandCard> findCards = new HashSet<>();
//        for (List<FoxHandCard> sequence : sequences) {
//            findCards.addAll(sequence);
//        }
        return new ArrayList<>(sequences.get(0));
    }

    /**
     * 找到满足顺子的所有组合
     * @param showCards
     * @param straightInterval 间隔最大值
     * @param straightMinNum 顺子的最小数量要求
     * @return
     */
    public List<List<FoxHandCard>> findAllStraightCards(List<FoxHandCard> showCards, int straightInterval, int straightMinNum) {
        List<List<FoxHandCard>> sequences = new ArrayList<>();
        List<FoxHandCard> currentSequence = new ArrayList<>();

        currentSequence.add(showCards.get(0));

        for (int i = 1; i < showCards.size(); i++) {
            FoxHandCard nowCard = showCards.get(i);
            FoxHandCard lastCard = showCards.get(i - 1);
            //点数1同时可以当14用
            //两个点数相减的绝对值不为0并且小于等于straightInterval,
            //两个点数相同往后找
            int lastCardPoint = lastCard.getPoint();
            if (i == 1 && lastCardPoint == 1) {
                //第一个如果是A
                lastCardPoint = getPointToScoreMap().size() + 1;
            }
            int offsetPoint = Math.abs(lastCardPoint - nowCard.getPoint());
            if (offsetPoint != 0 && offsetPoint <= straightInterval) {
                currentSequence.add(nowCard);

                if (i == showCards.size() - 1) {//最后一张找第一张是不是A
                    FoxHandCard firstCard = showCards.get(0);
                    offsetPoint = Math.abs(nowCard.getPoint() - firstCard.getPoint());
                    if (offsetPoint != 0 && offsetPoint <= straightInterval) {
                        currentSequence.add(firstCard);
                    }
                }
                if (currentSequence.size() >= 5) {//最多5张
                    sequences.add(new ArrayList<>(currentSequence));
                    // 重置当前序列
                    currentSequence.clear();
                }
            } else {
                // 如果当前序列长度大于或等于minLength，将其添加到结果列表中
                if (currentSequence.size() >= straightMinNum) {
                    sequences.add(new ArrayList<>(currentSequence));
                }
                // 重置当前序列
                currentSequence.clear();
                currentSequence.add(nowCard);
            }
        }

        // 检查最后一个序列
        if (currentSequence.size() >= straightMinNum) {
            sequences.add(currentSequence);
        }
        return sequences;
    }

    public List<FoxHandCard> getSameColorCards(List<FoxHandCard> showCards, Map<Integer, Set<Integer>> sameColorMap, int straightMinNum) {
        Map<Integer, List<FoxHandCard>> colorCardsMap = new HashMap<>();//统计同花色的数量
        //石头牌提前过滤,这里不会有石头牌
        for (FoxHandCard handCard : showCards) {
            int handColor = handCard.getColor();
            if (isAllColorHandCard(handCard.getReinforceEffect())) {
                handColor = 0;//万能花色用0表
            }
            Set<Integer> sameColors = sameColorMap.get(handColor);
            if (sameColors == null) {
                continue;
            }
            for (Integer color : sameColors) {
                List<FoxHandCard> colorCards = colorCardsMap.get(color);
                if (colorCards == null) {
                    colorCards = new ArrayList<>();
                    colorCardsMap.put(color, colorCards);
                }
                colorCards.add(handCard);
            }
        }
        int maxSameColorNum = 0;
        int maxColor = 0;
        for (Map.Entry<Integer, List<FoxHandCard>> entry : colorCardsMap.entrySet()) {//找到最多次数的花色
            int color = entry.getKey();
            int colorNum = entry.getValue().size();
            if (colorNum > maxSameColorNum) {
                maxSameColorNum = colorNum;
                maxColor = color;
            }
        }
        if (maxSameColorNum < straightMinNum) {
            return new ArrayList<>();
        }
        return colorCardsMap.get(maxColor);
    }

    public List<Integer> getGuideLottery(int lotteryNum) {
        if (lotteryNum < 0 || lotteryNum >= guideLotteryList.size()) {
            return new ArrayList<>();
        }
        return guideLotteryList.get(lotteryNum);
    }

    public int getInitGuaranteeNum() {
        return initGuaranteeNum;
    }

    public int getExRewardPoint() {
        return exRewardPoint;
    }

    public List<Integer> getGoldenRecallParams() {
        return goldenRecallParams;
    }

    public Map<Integer, Integer> getRecallLotteryRandomPool() {
        return new HashMap<>(recallLotteryRandomPool);
    }

    public Map<Integer, List<Integer>> getRecallBalanceParamsMap() {
        return recallBalanceParamsMap;
    }

    public List<Integer> getRecallCompareParams() {
        return recallCompareParams;
    }

    public BigDecimal getComparePowerScore() {
        return BigDecimal.valueOf(recallCompareParams.get(0)).multiply(BigDecimal.valueOf(recallCompareParams.get(1))).divide(BigDecimal.valueOf(1000));
    }

    public int getGoldenGuaranteeNum() {
        return goldenGuaranteeNum;
    }
}
